#!/usr/bin/env python
#
#       Results_tab.py
#       
#       Copyright 2009 Brandon Invergo <brandon@brandoninvergo.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.


import sys

try:
    import pygtk
    #tell pyGTK, if possible, that we want GTKv2
    pygtk.require("2.0")
except:
    #Some distributions come with GTK2, but not pyGTK
    pass

try:
    import gtk
    import gtk.glade
    
except:
    print "You need to install pyGTK or GTKv2 ",
    print "or set your PYTHONPATH correctly."
    print "try: export PYTHONPATH=",
    print "/usr/local/lib/python2.2/site-packages/"
    sys.exit(1)
    
from gobject import TYPE_STRING, TYPE_PYOBJECT
import pango
import Error_dialog
from MajeRe_Engine import REngException
import Data_group

class Results_tab:
    def update_results(self, data_group):
        seek_iter = self.results_treestore.get_iter_root()
        has_group = False
        
        while seek_iter:
            name = self.results_treestore.get_value(seek_iter, 0)
            if name == data_group.name:
                has_group = True
                break
            else:
                seek_iter = self.results_treestore.iter_next(seek_iter)
        
        if has_group:
            parent = seek_iter.copy()
            results_iter = self.results_treestore.iter_children(parent)
            cont = True
            while cont:
                cont = self.results_treestore.remove(results_iter)
        else:      
            if len(data_group.results_list) > 0:  
                parent = self.results_treestore.append(None, [data_group.name, "", data_group])

        for result in data_group.results_list:
            iter = self.results_treestore.append(parent, ["", result.get("analysis"), None])
            self.results_treestore.append(iter, ["", result.get("result"), None])
            self.results_treestore.append(iter, ["", result.get("notes"), None])
            path = self.results_treestore.get_path(iter)
            self.results_treeview.collapse_all()
            self.results_treeview.expand_row((path[0],), False)
            self.results_treeview.expand_row((path[0],path[1]), False)
            self.results_treeview.set_cursor(path)
            

    
    def resultscol_func(self, column, cell, model, iter):
        path = model.get_path(iter)
        text = model.get_value(iter, 1)
        if model.iter_depth(iter) == 1:
            cell.set_property('font', pango.FontDescription("normal bold"))
        else:
            if model.iter_depth(iter) == 2:
                if path[2] == 0:
                    cell.set_property('font', pango.FontDescription("monospace"))
                else:
                    cell.set_property('font', pango.FontDescription("normal"))
        cell.set_property('text', text)
        return
    
    def results_select_func(self, path):
        if len(path) == 2:
            self.note_button.set_sensitive(True)
            self.remove_button.set_sensitive(True)
            return True
        if len(path) > 2:
            path = (path[0], path[1])
            self.note_button.set_sensitive(True)
            self.remove_button.set_sensitive(True)
            self.results_treeview.set_cursor(path)
        else:
            self.note_button.set_sensitive(False)
            self.remove_button.set_sensitive(False)
        return False
    
    def on_remove(self, widget):
        cursor = self.results_treeview.get_cursor()[0]
        dg_iter = self.results_treestore.get_iter((cursor[0],))
        data_group = self.results_treestore.get_value(dg_iter, 2)
        
        analysis_iter = self.results_treestore.get_iter(cursor)
        analysis_name = self.results_treestore.get_value(analysis_iter, 1)
        
        data_group.remove_result(analysis_name)
        self.results_treestore.remove(analysis_iter)
        
        if self.results_treestore.iter_n_children(dg_iter) == 0:
            self.results_treestore.remove(dg_iter)
    
    def on_note(self, widget):
        cursor = self.results_treeview.get_cursor()[0]
        dg_iter = self.results_treestore.get_iter((cursor[0],))
        data_group = self.results_treestore.get_value(dg_iter, 2)
        
        analysis_iter = self.results_treestore.get_iter(cursor)
        analysis_name = self.results_treestore.get_value(analysis_iter, 1)
        
        dg_analysis = data_group.get_result(analysis_name)
        dg_notes = dg_analysis.get("notes")

        note_text = self.glade_gui.get_widget("Results_note_text")
        note_buffer = gtk.TextBuffer()
        note_buffer.set_text(dg_notes)
        note_text.set_buffer(note_buffer)

        response = self.note_dialog.run()
        
        if response == gtk.RESPONSE_OK:
            note_start = note_buffer.get_start_iter()
            note_end = note_buffer.get_end_iter()
            note_text = note_buffer.get_text(note_start, note_end)
                     
            data_group.edit_result(analysis_name, notes_text = note_text)
            
            dg_row = cursor[0]
            analysis_row = cursor[1]
            notes_path = (cursor[0], cursor[1], 1)
            notes_iter = self.results_treestore.get_iter(notes_path)
            
            self.results_treestore.set_value(notes_iter, 1, note_text)
        if response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
            pass
        self.note_dialog.hide()
        
    def on_results_row_activated(self, treeview, path, column):
        if treeview.row_expanded(path):
            treeview.collapse_row(path)
        else:
            treeview.expand_row(path, False)
    
    def __init__(self, parent_window, glade_gui):
        self.main_window = parent_window
        self.glade_gui = glade_gui
        self.error = Error_dialog.Error_dialog()
        
        callbacks = {"on_Results_remove" : self.on_remove,\
            "on_Results_note" : self.on_note,\
            "on_results_row_activated" : self.on_results_row_activated}
        self.glade_gui.signal_autoconnect(callbacks)
        
        self.results_treestore = gtk.TreeStore(TYPE_STRING, TYPE_STRING, TYPE_PYOBJECT)
        self.results_treeview = self.glade_gui.get_widget("Results_treeview")
        self.results_treeview.set_model(self.results_treestore)
        
        results_datagroupcol = gtk.TreeViewColumn("Data Group")
        self.results_treeview.append_column(results_datagroupcol)
        results_datagroupcell = gtk.CellRendererText()
        results_datagroupcol.pack_start(results_datagroupcell, True)
                
        self.results_resultscol = gtk.TreeViewColumn("Results")
        self.results_treeview.append_column(self.results_resultscol)
        results_resultscell = gtk.CellRendererText()
        self.results_resultscol.pack_start(results_resultscell, True)
        self.results_resultscol.set_cell_data_func(results_resultscell, self.resultscol_func)
        
        results_datagroupcol.add_attribute(results_datagroupcell, 'text', 0)
        self.results_resultscol.add_attribute(results_resultscell, 'text', 1)
        
        results_selection = self.results_treeview.get_selection()
        results_selection.set_mode(gtk.SELECTION_SINGLE)
        results_selection.set_select_function(self.results_select_func)
        
        self.note_button = self.glade_gui.get_widget("Results_note")
        self.remove_button = self.glade_gui.get_widget("Results_remove")
        
        self.note_dialog = self.glade_gui.get_widget("Results_note_dialog")
        self.note_dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        self.note_dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        
